package com.jhws.sys.appUser.api;

import java.util.HashMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jhws.business.comm.bo.TblCommDimBo;
import com.jhws.business.comm.service.ITblCommDimService;
import com.jhws.core.shiro.tokens.AppAuthToken;
import com.jhws.sys.user.bo.TblUserDimBo;
import com.jhws.util.StringUtils;
import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


import com.jhws.sys.appUser.bo.TblSipAcountDimBo;
import com.jhws.common.base.bo.JsonRespData;
import com.jhws.core.exception.UnauthorizedException;
import com.jhws.core.shiro.service.IOAuthService;
import com.jhws.sys.appUser.service.ITblSipAcountDimService;

/**
 * @author : Alex Tan
 * @Create : 2016-10-25 下午1:46:36
 * @Comment : app鉴权，获取临时token, 需要携带用户名与密码MD5, token时效取决于cache时效
 */
@RestController
@RequestMapping("/auth")
public class appAuth {

    @Autowired
    private ITblSipAcountDimService ISipAccountService;

    @Resource
    protected ITblCommDimService ITblCommDimService;

    @Autowired
    private IOAuthService IOAuthService;

    @SuppressWarnings({"rawtypes", "unchecked"})
    @RequestMapping("accessToken")
    @ResponseBody
    public HttpEntity token(HttpServletRequest request) throws Exception {
        String grantType = request.getParameter("grant_type");

        if (grantType == null) {
            throw new UnauthorizedException("-1", "accessToken", "无效参数 grant_type");
        } else if (grantType.equals("password")) {
            String username = request.getParameter("username");
            String password = request.getParameter("password");

            String accountId = ISipAccountService.isUserExist(username);
            if (accountId == null)
                throw new UnauthorizedException("-2", "accessToken", "用户不存在！");
            else {
                TblSipAcountDimBo User = ISipAccountService.findTblSipAcountDimById(accountId);
                if (!User.getPassword().equals(password))
                    throw new UnauthorizedException("-3", "accessToken", "密码错误！");
                else {
                    String romType = request.getParameter("romType");
                    if (StringUtils.isNotEmpty(romType) && !romType.equals(User.getRomType())) {
                        User.setRomType(romType);
                        ISipAccountService.save(User);
                    }
                    //生成Access Token
                    return new ResponseEntity(new JsonRespData("accessToken", 1, accessToken(username)), HttpStatus.valueOf(HttpServletResponse.SC_OK));
                }
            }
        } else if (grantType.equals("outdoor_password")) {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            TblCommDimBo commDimBo = ITblCommDimService.findTblCommDimByCommCode(username);
            if (commDimBo == null)
                throw new UnauthorizedException("-2", "accessToken", "用户不存在！");
            else {
                if (!commDimBo.getCommPassword().equals(password))
                    throw new UnauthorizedException("-3", "accessToken", "密码错误！");
                else {
                    //生成Access Token
                    return new ResponseEntity(new JsonRespData("accessToken", 1, accessToken(username)), HttpStatus.valueOf(HttpServletResponse.SC_OK));
                }
            }
        }
        return null;
    }

    private HashMap accessToken(String username) throws OAuthSystemException {
        OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
        final String accessToken = oauthIssuerImpl.accessToken();
        IOAuthService.addAccessToken(accessToken, username);
        HashMap<String, String> resp = new HashMap<>();
        resp.put("expires_in", String.valueOf(IOAuthService.getExpireIn()));
        resp.put("access_token", username + '-' + accessToken);
        return resp;
    }

    /**
     * 使用app端的token来注册到web端的session
     * 主要是因为app端鉴权使用的自定义的token流程,而H5为了复用一些web的API,需要有session鉴权
     *
     * @param appToken
     * @param commCode
     * @return
     */
    @RequestMapping("registerSessionWithToken")
    @ResponseBody
    private JsonRespData registerSessionWithToken(String appToken, String commCode) {
        String[] userToken = appToken.split("-");

        if (userToken.length == 2) {
            String username = IOAuthService.getUsernameByAccessToken(userToken[1]);

            if (userToken[0].equals(username)) {
                SecurityUtils.getSubject().login(new AppAuthToken(username, appToken));
                /* 如果小区编号不为空,就把session中写入该小区的合法web user */
                if (StringUtils.isNotEmpty(commCode)) {
                    Session session = SecurityUtils.getSubject().getSession();
                    TblUserDimBo user = new TblUserDimBo();
                    user.setCommCode(commCode);
                    session.setAttribute(TblUserDimBo.USER_INFO_REFERENCE, user);
                }
                return new JsonRespData("", 1, "");
            }
        }

        return new JsonRespData("", -1, "");

    }
}
